﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Dictionary.Core;

namespace WebCrawler
{
    public partial class GetDataForm : Form
    {
        private Thread threadUpdateDatabase;
        private bool updating = false;
        public GetDataForm()
        {
            InitializeComponent();
        }
        /// <summary>
        /// Method to load form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GetDataForm_Load(object sender, EventArgs e)
        {
            timerUpdateStatus.Enabled = true;
        }
        /// <summary>
        /// get all category from URL
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, EventArgs e)
        {
            String strUrl = txtUrlSource.Text.ToString().Trim();
            if (strUrl.Length > 0)
            {
                Crawler crawler = new Crawler(strUrl);
                List<Category> listCategory = crawler.getSource();
                listBoxResult.DataSource = listCategory;
                listBoxResult.DisplayMember = "title";
                listBoxResult.ValueMember = "link";

                txtUrlSource.ReadOnly = true;
            }
        }
        /// <summary>
        /// To get all category in source
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listBoxResult_Click(object sender, EventArgs e)
        {
            if (listBoxResult.SelectedItems.Count > 0)
            {
                String strUrl = listBoxResult.SelectedValue.ToString();

                Crawler crawler = new Crawler(strUrl);
                List<Category> listCategory = crawler.getCategory();
                listBoxCategory.DataSource = listCategory;
                listBoxCategory.DisplayMember = "title";
                listBoxCategory.ValueMember = "link";
            }
        }
        /// <summary>
        /// To get all Vocab in category
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listBoxCategory_Click(object sender, EventArgs e)
        {
            if (listBoxCategory.SelectedItems.Count > 0)
            {
                String strUrl = listBoxCategory.SelectedValue.ToString();

                Crawler crawler = new Crawler(strUrl);
                List<Vocabulary> listVocab = crawler.getVocabulary();
                listBoxVocab.DataSource = listVocab;
                listBoxVocab.DisplayMember = "value";
                listBoxVocab.ValueMember = "value";
            }
        }
        /// <summary>
        /// To update database
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnUpdateData_Click(object sender, EventArgs e)
        {
            String strUrl = txtUrlSource.Text.ToString().Trim();
            if ((strUrl.Length > 0) && (MessageBox.Show("Do you want to reget data?\n(This action will need a long time!)","Confirm:", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes))
            {
                // make thread to update database
                this.updating = true;
                this.btnUpdateData.Enabled = false;
                threadUpdateDatabase = new Thread(updateDatabase);
                threadUpdateDatabase.Start();
            }
        }
        /// <summary>
        /// Get status database
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timerUpdateStatus_Tick(object sender, EventArgs e)
        {
            lblStatus.Text = DateTime.Now.ToLongTimeString() + "\nCategory count : " + Category.count().ToString() + " - Vocab count : " + Vocabulary.count().ToString();
        }
        /// <summary>
        /// Method to update database by Thread
        /// </summary>
        private void updateDatabase()
        {
            Source source = new Source();
            source.id = 1;
            source.select();
            GetData getData = new GetData(source.url);
            getData.Save();
            this.updating = false;
            MessageBox.Show("Update database success.\nYou have : \n\t" + Category.count().ToString() + " category(s).\n\t" + Vocabulary.count().ToString() + " vocab(s).");
        }
        /// <summary>
        /// Method to set status by Thread
        /// </summary>
        /// <param name="strText"></param>
        private void setStatus(String strText)
        {
            if (lblStatus.InvokeRequired)
            {
                lblStatus.BeginInvoke(new MethodInvoker(delegate() { setStatus(strText); }));
            }
            else
            {
                lock (lblStatus)
                {
                    lblStatus.Text = strText;
                }
            }
        }

        /// <summary>
        /// Method to do when form close
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GetDataForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.updating)
            {
                if (MessageBox.Show("Do you want to close form?\n(Your updating will be cancel!)", "Confirm:", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                {
                    // to stop thread
                    try
                    {
                        this.threadUpdateDatabase.Abort();
                    }
                    catch (Exception)
                    {
                    }
                    timerUpdateStatus.Enabled = false;

                    e.Cancel = false;
                }
                else
                {
                    e.Cancel = true;
                }
            }
        }
    }
}
